package cz.acies.uniql.dialect;

import java.sql.*;
import java.util.*;


import cz.acies.uniql.connect.*;
import cz.acies.uniql.metadata.FieldMetaData;
import cz.acies.uniql.metadata.IndexesMetaData;
import cz.acies.uniql.metadata.PrimaryKeyMetaData;
import cz.acies.uniql.metadata.TableMetaData;
import cz.acies.uniql.sql.SelectQuery;
import cz.acies.uniql.sql.element.UniQLField;
import cz.acies.uniql.sql.element.UniQLOrderBy;
import cz.acies.uniql.sql.functions.SQLFunc;
import cz.acies.uniql.sql.functions.SQLSpecFunc;

public class FirebirdDialect extends Dialect
{
	// DBMetaData variables
	// TableMetaData variables
	// FieldMetadata variables
	// PrimaryKeyMetaData variables
	// IndexMetaData variables
	
	// Convert Element variables
	// Convert values variables

	public FirebirdDialect() {
		
		registerColumnType(Types.BIT, "smallint" );
		registerColumnType(Types.BIGINT, "numeric(18,0)" );
		registerColumnType(Types.SMALLINT, "smallint" );
		registerColumnType(Types.TINYINT, "smallint" );
		registerColumnType(Types.INTEGER, "integer" );
		registerColumnType(Types.CHAR, "char($l)" );
		registerColumnType(Types.VARCHAR, "varchar($l)" );
		registerColumnType(Types.FLOAT, "float" );
		//getColumnTypes().registerColumnType("DOUBLE", "double($p,$s)" );
		registerColumnType(Types.DOUBLE, "numeric($p,$s)" );
		registerColumnType(Types.TIMESTAMP, "timestamp" );
		registerColumnType(Types.TIMESTAMP, "timestamp" );
		registerColumnType(Types.DATE, "timestamp" );
		registerColumnType(Types.TIME, "timestamp" );
		registerColumnType(Types.VARBINARY, "blob" );
		registerColumnType(Types.NUMERIC, "numeric($p,$s)" );
		registerColumnType(Types.BLOB, "blob" );
		registerColumnType(Types.LONGVARCHAR, "blob" );
		registerColumnType(Types.CLOB, "blob sub_type 1" );
		
		//System.out.println("FirebirdDialect.columnTypes = "+getColumnTypes());
		
		// DBMetaData variables
		// TableMetaData variables
		// FieldMetadata variables
		FMD_APPEND_DEFAULT_IFNULL = false;
		FMD_IDENTITY_BUILD_PART = "";
		// PrimaryKeyMetaData variables
		PK_CONSTRAINTED = true;
		// IndexMetaData variables		
		// Convert Element variables
		// Convert values variables

	}

	// ----- Quoted methods ---------------------------------------------------
	
	public String LQ() { return "\""; }
	public String RQ() { return "\""; }
	public String CTI_LQ() { return "\""; }
	public String CTI_RQ() { return "\""; }

	// ----- Database connection methods --------------------------------------
	
	public String getColumnTypeString(int sqltype, int length, int scale) {		
		/*
		String type = getColumnTypes().getColumnTypeName(sqltype);
		
		//System.out.println("type: "+type);
		if (type.equals("numeric($p,$s)")) {
			if (length > 12) length = 12; 
		}
		
		String s = getColumnTypes().parse(
			type,
			new Integer(length),
			new Integer(scale)
		);
		return s;
		*/
		return "";
	}

	//public String generateSQLConnUrl(Properties prop) throws SQLException {
	public String generateSQLConnUrl(SQLConnect sqlconn) throws SQLException {
		
		//"jdbc:firebirdsql:localhost/3050:c:/database/firebird/smart4web.fdb";
		String url = "jdbc:firebirdsql:";

		String host = (String)sqlconn.getHost();
		if (host == null) throw new SQLException("Host in URL address is .NULL.");
		url += ((host.equals("localhost")) ? "" : "//") + host + "";

		String port = (String)sqlconn.getPort();
		if (port == null) throw new SQLException("Port name in URL address is .NULL.");
		if (port != null){
			url += ":"+port;
		}
		String database = (String)sqlconn.getDatabase();
		if (database == null) throw new SQLException("Database name in URL address is .NULL.");
		if (database != null){
			url += "/"+database;
		}
		return url;
	}
	
	// ----- ColumnType methods -----------------------------------------------
	
	// ----- ReservedKeywords methods -----------------------------------------
	
	// ----- Fn Methods -------------------------------------------------------
	
	//* ***********************************************************************
	//* Database Mapping methods
	//* ***********************************************************************
	
	// ----- DBMetaData methods -----------------------------------------------
	
	// ----- TableMetaData metdods --------------------------------------------
	
	// ----- FieldMetadata methods --------------------------------------------

	// ----- PrimaryKey Constraint --------------------------------------------
	
	public String getPKConstraintPrefix() {
		return "PK_";
	}
	
	public boolean isPKConstrainted() { 
		return true; 
	}
	
	// ----- IndexMetaData methods --------------------------------------------
	
	// ----- Convert Element methods ------------------------------------------
	
	// ----- DDL methods ------------------------------------------------------
	/*
	public String getCreateTableString(TableMetaData tbmd) {
		String s = "CREATE TABLE \""+tbmd.getName()+"\" (\n";
		for (int i = 0; i < tbmd.getFields().size(); i++) {
			FieldMetaData fmd = (FieldMetaData)tbmd.getFields().elementAt(i);
			//s += (String)getFields().get(i);
			s += fmd.toString();
			s += (i < tbmd.getFields().size()-1) ? ",\n" : "\n"; 
		}
		PrimaryKeyMetaData pkmd = tbmd.getPrimaryKey();
		if (pkmd != null) {
			String columnname = pkmd.getColumn();
			s += ",\n"+"CONSTRAINT PK_"+tbmd.getName()+" PRIMARY KEY ("+columnname+")"+"\n";
		}
		s += ")";
		return s;		
	}
	*/
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getCreateTableFieldString(com.smart4web.db.structure.FieldMetaData)
	 */
	public String getCreateTableFieldString(FieldMetaData fmd) {
		String s = "";
		if (fmd.isPrefix()) s += this.LQ() + fmd.getTable() + this.RQ() + ".";
		s += (isKeyword(fmd.getName())) ? 
		    this.LQ()+(fmd.getName()+"_")+this.RQ() : 
		    this.LQ()+fmd.getName()+this.RQ();
		    
		fmd.setTypeName(this.getColumnTypeString(
		    fmd.getSqlType(), fmd.getSize(), fmd.getDecimal())
		);
		s += " " + fmd.getTypeName() + " ";
	
		if (fmd.isNullable()) {
			if (fmd.hasValue()) {
				s += "DEFAULT " + fmd.getValue() + " ";
			}
			s += this.getNullColumnString();
		} else {
			s += "DEFAULT " + fmd.getValue() + " ";
			s += " NOT NULL ";
		}
		return s;
	}

	public String getDropTableString(String schema,String table) {
		return "DROP TABLE \""+table+"\"";
	}
	
	public String getCreateIndexesString(IndexesMetaData ixmd) {
		Vector list = getCreateIndexesList(ixmd);
		String s = "";
		for (Enumeration e = list.elements() ; e.hasMoreElements() ;) {
			String query = (String)e.nextElement();
			s += query + ((e.hasMoreElements()) ? "; " : "");
		}	 		
		return s;
	}

	public Vector getCreateIndexesList(IndexesMetaData ixmd) {
		Vector list = new Vector();
		for (Enumeration e = ixmd.elements(); e.hasMoreElements();) {
			Hashtable params = (Hashtable)e.nextElement();
			Hashtable columns = (Hashtable)params.get("columns");
			
			String name = (String)params.get("INDEX_NAME");
				
			String query = "";
			if (name.equals("PRIMARY")) {
			} else {
				//String asc_desc = (String)params.get("ASC_OR_DESC");
				boolean nonunique = ((Boolean)params.get("NON_UNIQUE")).booleanValue();
				
				name = "IDX_"+ixmd.getTable().toUpperCase()+"_"+name.toUpperCase()+" ";
				String colstr = "(";
				for (int i = 0; i < columns.size(); i++) {
					String columnname = (String)columns.get(new Integer(i+1));
					columnname = (isKeyword(columnname)) ? (columnname+"_") : columnname;
					colstr += columnname; 					
					if (i < columns.size()-1) colstr += ",";
				}
				colstr += ")";
				
				query = "CREATE ";
				if (!nonunique) { 
					query += "UNIQUE ";
				}
				//query += asc_desc;
				query += "INDEX "+name+"ON \""+ixmd.getTable()+"\" "+colstr;
				list.addElement(query);
			}
		}
		return list;
	}
	
	// ----- Convert Values methods -------------------------------------------
	
	public String getValueTime(String value) {
		return "'"+value+"'";
	}
	
	public String getValueDouble(String value) {
		return "'"+value+"'";
	}
	
	// ----- DDL methods ------------------------------------------------------

	// ----- FullText methods -------------------------------------------------

	// ----- LOCK & UNLOCK TABLE methtods -------------------------------------

	// ----- QueryRebuilder methods -------------------------------------------
	
	public synchronized String generateLimitQuery(SelectQuery query) {
		return "";
	}
}

/*
CREATE DATABASE 'C:\database\firebird\s4w.gdb'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE = 16384
DEFAULT CHARACTER SET DOS852 

CREATE DATABASE 'C:\database\firebird\smart4web.gdb'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE = 16384

*/
